<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<html>
<head>
    <title>Ajaxlab Command Prompt</title>
    <link rel='stylesheet' href='styles.css' type='text/css' />
  
        <style type="text/css">
<!--
.style1 {font-size: 16}
-->
        </style>
</head>
<body>

<div id="body">
    <table width="100%" border="0" cellspacing="0" cellpadding="0">
      <tr>
        <td valign="top"><a href="index.html">Home </a>- Write Plug Ins </td>
      </tr>
      <tr>
        <td width="77%" valign="top"><h1>Write Your Command Plugins. </h1>
          <p>How is plugin developed? I'll use the <a href="CMDLogParserDemo.aspx">&quot;Web Stats&quot; plugin</a> as an example. <br>
            <br>
1. Take a look at the Command Plugin Template. It's availabe at /ScriptLibrary/AjaxLabCommandPrompt/Engine/Plugins/Your_Commands_Template.js
          <div>
            <pre>  	<br>Type.registerNamespace(&quot;AjaxLab.Engine.Plugins&quot;);<br>AjaxLab.Engine.Plugins.<strong>YourCommandClassName</strong>= function()<br>{<br>	var customCommands = &quot;<strong>YourCommand1|</strong>Yo<strong>urCommand2&quot;</strong>;<br>	var instance = this;<br>	AjaxLab.Engine.Plugins.BaseCommands.initializeBase(this);<br>	this.registerCommands(customCommands);<br>	<br>	/* Implement the Plug In here */<br>	<br>	this.processCommands = function(inputtext) {<br>		<br>		<br>    }<br>}<br>AjaxLab.Engine.Plugins.<strong>YourCommandClassName</strong>.registerClass('AjaxLab.Engine.Plugins.<strong>YourCommandClassName</strong>', AjaxLab.Engine.Abstract.Commands);</pre>
          </div>
          <p>All we have to do is to replace the three bolded &quot;YourCommandClassName&quot; with our own class name (note, our complete class name will be <span class="style1">&quot;AjaxLab.Engine.Plugins.<strong>YourCommandClassName&quot; </strong></span>and the rest is taken cared by the command prompt itself. The bolded <strong>&quot;YourCommand1|YourCommand2&quot;</strong> will be our custom commands. More on this later. <br>
              <br>
            2. Okay, Let's code our IIS Log plugin. <br>
  <br>
            First, let's call our plugin &quot;MSIISLogParser&quot;, change the template and save it as AjaxLabMSIISLogParser.js. So base on the command template above, it becomes <br>
  <br>
          <div>
            <pre>  	<br>Type.registerNamespace(&quot;AjaxLab.Engine.Plugins&quot;);<br>AjaxLab.Engine.Plugins.<strong>MSIISLogParser</strong>= function()<br>{<br>	var customCommands = <strong>&quot;YourCommand1|YourCommand2&quot;;</strong><br>	var instance = this;<br>	AjaxLab.Engine.Plugins.BaseCommands.initializeBase(this);<br>	this.registerCommands(customCommands);<br>	<br>	/* Implement the Plug In here */<br>	<br>	this.processCommands = function(inputtext) {<br>		<br>		<br>    }<br>}<br>AjaxLab.Engine.Plugins.<strong>MSIISLogParser</strong>.registerClass('AjaxLab.Engine.Plugins.<strong>MSIISLogParser</strong>', AjaxLab.Engine.Abstract.Commands)</pre>
          </div>
          </p>
          <br>
          So again, our full class name is &quot;<span class="style1">AjaxLab.Engine.Plugins.<strong>MSIISLogParser</strong></span>&quot;<br>
          <br>
          <p>3. Register our own commands. 
          <p>Now, Let's add our own commands. I'm thinking of using &quot;webstats&quot; or &quot;logparser&quot;, oh hell, let's use both. So let's replace the bolded <span class="style1"><strong>&quot;YourCommand1|YourCommand2&quot;</strong>with our own then. </span></p>
          <div>
            <pre>  	<br>Type.registerNamespace(&quot;AjaxLab.Engine.Plugins&quot;);<br>AjaxLab.Engine.Plugins.<strong>MSIISLogParser</strong>= function()<br>{<br>	var customCommands = <strong>&quot;webstats||logparser&quot;;</strong><br>	var instance = this;<br>	AjaxLab.Engine.Plugins.BaseCommands.initializeBase(this);<br>	this.registerCommands(customCommands);<br>	<br>	/* Implement the Plug In here */<br>	<br>	this.processCommands = function(inputtext) {<br>		<br>		<br>    }<br>}<br>AjaxLab.Engine.Plugins.<strong>MSIISLogParser</strong>.registerClass('AjaxLab.Engine.Plugins.<strong>MSIISLogParser</strong>', AjaxLab.Engine.Abstract.Commands)</pre>
          </div>
          <br>
          <p>4. How do we know what commands that the user entered? <br>
              <br>
            Notice this &quot;this.processCommands&quot; function? That's where we are going to implement our own logic. Command prompt by default, pass the commands that the user entered on each line before they hit the &quot;ENTER&quot; key or carraige return and pass them into the &quot;inputtext&quot; parameter. For example: <br>
  <br>
          <div>
            <pre> <br>http://www.ajaxlab.com&gt;webstats top visitors

<em><strong>inputtext is &quot;webstats top visitors&quot;</strong></em>
          </pre>
          </div>
          </p>
          <br>
5. Process Commands. <br>
<br>
Okay. Now, let' s take &quot;webstats top visitors&quot; command as an example and see how we are going to process it. <br>
<br>
For this plug-in, I decided to use MSLogParser to parse the IIS log files and because MSSLogParser works nicely with C#, I decided to go all .NET with this plugIn and
use AjaxPro.NET as well. (I encourage other plug-ins in scriptaculous/php to be submitted )
<p><br>
<div>
  <pre>this.processCommands = function(inputtext) {<br>		instance.Log4J.setRootLevel(instance.Log4J.LevelTypes.Debug);<br>		instance.Log4J.Debug(&quot;LogParser command detected and input string is :&quot;+inputtext);<br>		var command     = inputtext.split(&quot; &quot;);<br>		if (command == null)<br>		{<br>			instance.Log4J.Debug(&quot;LogParser Command null&quot;);<br>		}<br>		instance.Log4J.Debug(&quot;Logparser input string command[0]:&quot;+command[0]);<br>		i<em><strong>f(command[0].toUpperCase() == &quot;LOGPARSER&quot; || &quot;WEBSTATS&quot;)</strong></em><br>		{<br>			if(command[1].toUpperCase() <em><strong>== &quot;TO</strong></em>P&quot;)<br>			{<br>				if(command[2].toUpperCase() ==<em><strong>&quot;VISITO</strong></em>RS&quot;)<br>				{<br>					instance.Log4J.Debug(&quot;Start retrieving Top IPCount&quot;);<br>				<em><strong>	AjaxLabCmd.CMDLogParserDemo.SelectTopVisits(command[3],this.IPCountCallBack</strong></em>);<br>				}<br>				else{<br>					instance.Console.printToConsole(command[2]+&quot; is not recognized as an internal or external command&quot;);<br>				}<br>			}<br><br>			else{<br>				instance.Log4J.Debug(&quot;LogParser command :&quot;+command[1]+&quot; not recognized&quot;);<br>				instance.Console.printToConsole(inputtext+&quot; is not recognized as an internal or external command&quot;);<br>			}<br>		}<br>		else{<br>				instance.Log4J.Debug(&quot;LogParser base command not found&quot;);<br>				instance.Console.printToConsole(inputtext+&quot; is not recognized as an internal or external command&quot;);<br>		}<br>    }<p>this.IPCountCallBack = function(res)
{ <br>
		instance.Log4J.Debug(&quot;Start Top Viists Print&quot;);
			instance.Console.println(&quot;&quot;);
			instance.Console.println(&quot;IP			Count&quot;);
			instance.Console.println(&quot;----------		----------&quot;);<br>
			if(res.value.Tables[0]!=null)
			{ 
				for(var i=0; i&lt;res.value.Tables[0].Rows.length; i++)
				{
					instance.Console.println(res.value.Tables[0].Rows[i].IP + &quot;              : &quot; + res.value.Tables[0].Rows[i].Total);
			}
			}
			else{
				instance.Console.println(&quot;No values&quot;);
			}
			instance.Console.newPrompt();
			instance.Log4J.Debug(&quot;Endclear Top Visits Print&quot;);<br>}</pre>
</div>
<p>&nbsp;</p>
What's going on Here? If you look closely, it's simply doing simple javascript actions. First, it parses the incoming command &quot;webstats top visitors&quot; into an array sepearated via spaces ( inputtext.split(&quot; &quot;) ). Second, for the command &quot;webstates top visitors&quot;, if all three words are found, then it uses AjaxPro.NET to do an AJAX asynchrounous call to the backend C# method: <span class="style1"><em><strong> <br>
        <br>
  AjaxLabCmd.CMDLogParserDemo.SelectTopVisits(command[3],this.IPCountCallBack</strong></em>);</span><br>
  <br>
  This is a syntax specific to AjaxPro.NET. <strong>AjaxLabCmd</strong> is the backend Namespace. <em><strong>CMDLogParserDemo </strong></em>is the backend class to parse the IIS Log file. <strong>SelectTopVisits </strong>is the class method that does the specfic query, <strong>command[3]</strong> is an optional &quot;number of results&quot; parameter passed to the backend and <strong>this.IPCountCallBack </strong>is the ajax call back method for us to handle the result of the Ajax Query which simply loops through the result and spit it back onto the command prompt screen.  Now, for the demostration, I won't go into the backend implementation as how exactly I used MS LogParser 2.2 to query the IIS log files, if you are interested, then please let me know and I'll blog a post about it. <br>
  <br>
  Again, exactly how and what you used to call your backend is up to you. You can use Dojo, scriptaculous, php or whatever is your favorite. At this point, the magic is in your hands. <br>
  <br>
  Note, there are serveral default methods that are available to plug-in authors. <br>
  <br>
  a). instance.Log4J.Debug() method is available to you if you want to output some debugging information. <br>
  b). instance.Console.printToConsole() is used to print anything you want onto the console screen. <br>
  c). instance.Console.newPrompt() simply output another prompt root like &quot;c:/:&gt; &quot; or in this demo, it's &quot;http://www.ajaxlab.com :&gt;&quot; <br>

  <br>
  There are more methods available to you. Please take a look at the <a href="API.html">API section</a> for more detail. 
  <p>6. Register this library with 
/ScriptLibrary/AjaxLabCommandPrompt/Engine/Core/Cmd.js, so command prompt knows to instantiate the plugin. 
	<pre>Type.registerNamespace(&quot;AjaxLab.Engine.Core&quot;);<br>AjaxLab.Engine.Core.Cmd= function(CommandPromptContainer, CommandPromptTextArea, DebugArea, CommandPromptRoot)<br>{<br>	AjaxLab.Engine.Core.Cmd.initializeBase(this, [CommandPromptContainer, CommandPromptTextArea, DebugArea, CommandPromptRoot]);<br>	this.InitPlugIns =	function()<br>	{<br>		//Base Command Plugin. Try not to mess with it. 
	<br>		this.registerCommandsPlugin(&quot;ScriptLibrary/AjaxLabCommandPrompt/Engine/Plugins/AjaxLabBaseCommands.js&quot;,<br>								&quot;AjaxLab.Engine.Plugins.BaseCommands&quot;<br>								);<br>	<br>		<br>		//Register Your Plugins Here<br>	<strong>	this.registerCommandsPlugin(&quot;ScriptLibrary/AjaxLabCommandPrompt/Engine/Plugins/AjaxLabMSIISLogParser.js&quot;,<br>								&quot;AjaxLab.Engine.Plugins.MSIISLogParser&quot;<br>								</strong>);<br><br>				<br>	}<br>	<br>	<br>}<br>AjaxLab.Engine.Core.Cmd.registerClass('AjaxLab.Engine.Core.Cmd', AjaxLab.Engine.Abstract.Cmd);a
	</pre>
	The first Parameter is the path to our plugin library and the second parameter is our <strong>FULL class name 
	</strong>
	<h2>Credits</h2>
<p>AjaxLab.com</p></td>
      </tr>
    </table>
</body>
</html>